package at.ac.tuwien.big.form.htmlgen

import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.xtext.generator.IFileSystemAccess
import org.eclipse.xtext.generator.IGenerator
import org.eclipse.emf.ecore.EObject
import at.ac.tuwien.big.form.Form
import at.ac.tuwien.big.form.Page
import at.ac.tuwien.big.form.InputField
import at.ac.tuwien.big.form.SelectionField
import at.ac.tuwien.big.form.SelectionCondition
import at.ac.tuwien.big.form.PageElement
import at.ac.tuwien.big.form.Heading
import at.ac.tuwien.big.form.Paragraph
import at.ac.tuwien.big.form.List
import at.ac.tuwien.big.form.TextField
import at.ac.tuwien.big.form.TextArea
import at.ac.tuwien.big.form.SelectionFieldType
import org.eclipse.emf.common.util.URI

class Form2HTMLGenerator implements IGenerator {

	override doGenerate(Resource resource, IFileSystemAccess fsa) {
		for (EObject object : resource.contents) {
			switch(object) {
				Form: object.generateFile(fsa, resource.URI)
			}
		} 
	}

	def generateFile(Form form, IFileSystemAccess fsa, URI uri) {
		fsa.generateFile(uri.lastSegment.replaceAll(".form",".html"), form.generateHTML)	
	}
	
	def generateHTML(Form form)'''
		<!DOCTYPE html>
		<html lang="en">
			«form.generateHEAD»
			«form.generateBODY»
		</html>
	'''
	
	//generated head with includes and initializes JavaScript
	def generateHEAD(Form form)'''
		<head>
			<title>«form.welcomePage.title»</title>
			<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
			<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
			<link href="../assets/form.css" rel="stylesheet" media="screen"/>
			<script src="../assets/jquery-1.10.2.min.js" type="text/javascript"></script>
			<script src="../assets/form.js" type="text/javascript"></script>
			<script type="text/javascript">
			$(document).ready(
				function(){
					form.init();
					«FOR page : form.pages»
						«page.registerMandatory»
					«ENDFOR»
					
					«FOR page : form.pages»
						«page.registerElements»
					«ENDFOR»
					
					«FOR page : form.pages»
						«page.registerVisibleCondition»
					«ENDFOR»
				});
			</script>	
		</head>
	'''
	
	//differs mandatory and optional pages
	def registerMandatory(Page page)'''
		«FOR element : page.elements»
			«IF element instanceof InputField»
				«var inputField = element as InputField»
				«IF inputField.mandatory»
					form.registerMandatory('«inputField.elementId»');
				«ELSE»
					form.registerOptional('«inputField.elementId»');
				«ENDIF»
			«ENDIF»
		«ENDFOR»
	'''
	
	//registers an element
	def registerElements(Page page)'''
		«FOR element : page.elements»
			form.registerElement('«element.elementId»');
		«ENDFOR»
	'''
	
	//registers visibility conditions
	def registerVisibleCondition(Page page)'''
		«FOR condition : page.visibilityConditions»
			«var selectionCondition = condition as SelectionCondition»
			«FOR element : condition.concernsElements»
				form.registerConditional('«selectionCondition.item.field.elementId»', '«selectionCondition.item.label»',
				['«element.elementId»']
				);
				«ENDFOR»
		«ENDFOR»
	'''
	
	//generates body 
	def generateBODY(Form form)'''
		<body>
			<div class="container">
				«FOR page : form.pages»
					<div class="page">
						<div class="well">
							<form action="#">
								<fieldset>
									«FOR pageElement : page.elements»
										«pageElement.differPageElements»		
									«ENDFOR» 
								</fieldset>
							</form>
						</div>
					</div>		
				«ENDFOR»
			</div>
		</body>
	'''
	
	//differs between the PageElements
	def differPageElements(PageElement pe){
		switch pe {
			Heading : pe.generateHeading
			Paragraph: pe.generateParagraph
			List: pe.generateList
			TextField: pe.generateTextField
			TextArea: pe.generateTextArea
			SelectionField: pe.generateSelectionField
		}
	}	
	
	//differs between checkbox, combobox and radio they are all SelectionFields
	def generateSelectionField(SelectionField sf)'''
		<div class="control-group">
			«IF sf.selectionFieldType==SelectionFieldType.CHECKBOX»
				<label class="lone" id="label_for_«sf.elementId»">«sf.label»</label>
				<div class="controls" id="«sf.elementId»">
				«var idx = -1»
					«FOR item : sf.items »
						<label class="checkbox" for="«sf.elementId»_«idx=idx+1»">
							<input type="checkbox" value="«item.label»" name="«sf.elementId»" id="«sf.elementId»_«idx»"«IF item.selected» checked="checked"«ENDIF» /> «item.label»
						</label>
					«ENDFOR»
				</div>			
			«ELSEIF sf.selectionFieldType==SelectionFieldType.COMBOBOX»
				<label for="«sf.elementId»" class="lone">«sf.label»</label>
				<div class="controls">
					<select id="«sf.elementId»">
					«FOR item : sf.items»
						<option value="«item.label»">«item.label»</option>
					«ENDFOR»
					</select>
				</div>
			«ELSE»
				<label class="lone" id="label_for_«sf.elementId»">«sf.label»</label>
				<div class="controls" id="«sf.elementId»">
				«var idx = -1»
					«FOR item : sf.items »
						<label class="radio" for="«sf.elementId»_«idx=idx+1»">
							<input type="radio" value="«item.label»" name="«sf.elementId»" id="«sf.elementId»_«idx»"«IF item.selected» checked="checked"«ENDIF» /> «item.label»
						</label>	
					«ENDFOR»
				</div>
			«ENDIF»
		</div>					
	'''
	
	//TextArea
	def generateTextArea(TextArea ta)'''
		<div class="control-group">
			<label for="«ta.elementId»">«ta.label»</label>
			<div class="controls">
				<textarea id="«ta.elementId»"></textarea>
			</div>
		</div>
	'''
	
	//checks if TextField is encrypted
	def generateTextField(TextField tf)'''
		<div class="control-group">
			<label for="«tf.elementId»">«tf.label»</label>
			<div class="controls">
				<input type="text" id="«tf.elementId»"«IF tf.encrypted» type="password"«ENDIF»/>
			</div>
		</div>
	'''
	
	//differs between ordered and unordered lists
	def generateList(List li)'''
		«IF li.ordered»
			<ol id="«li.elementId»">
				«FOR item : li.items»
					<li>«item.label»</li>
				«ENDFOR»
			</ol>
		«ELSE»
			<ul id="«li.elementId»">
				«FOR item : li.items»
					<li>«item.label»</li>
				«ENDFOR»
			</ul>
		«ENDIF»
	'''
	
	//simple Paragraph
	def generateParagraph(Paragraph par)'''
		<p id="«par.elementId»">«par.content»</p>
	'''
	
	//different heading levels
	def generateHeading(Heading hea)'''
		«IF hea.level==1»
			<h1 id="«hea.elementId»">«hea.content»</h1>
		«ELSEIF hea.level==2»
			<h2 id="«hea.elementId»">«hea.content»</h2>
		«ELSE»
			
		«ENDIF»
	'''
}
